/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package grex.WekaModels;

import grex.WekaModels.WekaPredictiveModel;
import grex.Data.ArffTableModel;
import grex.ErrorManagement.ErrorManager;
import grex.Data.Prediction;
import grex.Data.PredictionContainer;
import grex.IPredictiveModel;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import weka.attributeSelection.AttributeSelection;
import weka.attributeSelection.CfsSubsetEval;
import weka.attributeSelection.GreedyStepwise;
import weka.classifiers.trees.M5P;
import weka.core.Instance;
import weka.core.Instances;
import wekaGrexBridge.M5PReg;
import wekaGrexBridge.WekaArffTableModel;

/**
 *
 * @author RIK
 */
public class GrexPrioM5P extends WekaPredictiveModel{
    private M5P m5p;

    public GrexPrioM5P(ArffTableModel data){
        super(data,new M5P());
        m5p = (M5P) model;
        m5p.setUseUnsmoothed(true);
        m5p.setBuildRegressionTree(true);
    }
    public String getName(){
        return "M5P-Reg-US";
    }
    
    public void train() {
        try {
            model.buildClassifier(wekaTrain);
            execute(pcTrain);//set values in prediction container
            trained = true;
        } catch (Exception ex) {
            ErrorManager.getInstance().reportError(ex);
        }
    }
    
        private void performAttributeSelection(){
             AttributeSelection filter = new AttributeSelection();  // package weka.filters.supervised.attribute!
      CfsSubsetEval eval = new CfsSubsetEval();
      GreedyStepwise search = new GreedyStepwise();
         try {
       search.setSearchBackwards(true);

      filter.setEvaluator(eval);
      filter.setSearch(search);
      filter.SelectAttributes(wekaTrain);
      wekaTrain = filter.reduceDimensionality(wekaTrain);
      wekaTest = filter.reduceDimensionality(wekaTest);
            System.out.println(filter.selectedAttributes());
            System.out.println("nr:" + filter.numberAttributesSelected());
        } catch (Exception ex) {
            Logger.getLogger(WekaPredictiveModel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public double getNrOfNodes(){
        try {            
            return calcNumberOfNodes(m5p.graph());
        } catch (Exception ex) {
            ErrorManager.getInstance().reportError(ex);
        }
        return -999;
    }
        @Override
        public void execute(PredictionContainer pc) {
        for (Prediction p : pc.values()) {

            try {
                Instance instance = wekaArffTableModel.getInstance(p.getInstance(),wekaTrain);//wekaTrain is just used to set the Dataset in the instance
                double prediction;
                prediction = Math.max(model.classifyInstance(instance),0);
                
                p.setProbs(model.distributionForInstance(instance));
                p.setPrediction(prediction);
             
            } catch (Exception ex) {
                ErrorManager.getInstance().reportError(ex);
            }

        }
    }
    
    @Override
    public String toString(){
        try {
            return m5p.graph();
        } catch (Exception ex) {
            return "ERROR";
        }
    }
    
}
